function surface = lpcvd_2DSurface(varargin)
% lpcvd_2DSurface Constructor function
% SYNTAX:
%   lpcvd_2DSurface()
%   lpcvd_2DSurface(s)
%   lpcvd_2DSurface(filename,domain_size,length_unit)
%   lpcvd_2DSurface(h,x,y,length_unit)
%
% FIELDS:
% - h
% - x
% - y
% - site_width
% - layer_thickness
% - length_unit
%
% NOTE: The unit of site width MUST be the SAME as that of layer thickness,
%       otherwise, the meaning of slope would be very confusing.

switch nargin
    % lpcvd_2DSurface(): default constructor
    case 0     
        surface.h = [];
        surface.x = [];
        surface.y = [];
        
        surface.length_unit = 'nm';
        surface.site_width = 1;
        surface.layer_thickness = 1;   
        
        surface.r2 = [];
        surface.m2 = [];
        surface = class(surface,'lpcvd_2DSurface');                
    % lpcvd_2DSurface(s): copy constructor
    case 1    
        if(isa(varargin{1},'lpcvd_2DSurface'))
            surface = varargin{1};        
        else
            error('The only input must be of class lpcvd_2DSurface');
        end
    % lpcvd_2DSurface(filename,domain_size,length_unit): from file      
    case 3
        if(ischar(varargin{1}))
            filename = varargin{1};        
            surface.h = dlmread(filename);
            surface.h = surface.h';
            
            site_number_x = size(surface.h,1);
            site_number_y = size(surface.h,2);
            assert(site_number_x==site_number_y);           
            surface.length_unit = varargin{3};
            surface.site_width = varargin{2}/site_number_x;            
            surface.x = surface.site_width*(0:(site_number_x-1))';
            surface.y = surface.site_width*(0:(site_number_y-1))';
            
            surface.r2 = calc_r2(surface);
            surface.m2 = calc_m2(surface);
            surface = class(surface,'lpcvd_2DSurface');
        else
            error('Wrong argument type');
        end
    % lpcvd_2DSurface(h,x,y,length_unit): from data
    case 4
        h = varargin{1};
        x = varargin{2};
        y = varargin{3};
        assert(length(x)==length(y));
        assert(length(x)==size(h,1));
        assert(length(x)==size(h,2));

        surface.h = varargin{1};
        surface.x = varargin{2};
        surface.y = varargin{3};
        surface.length_unit = varargin{4};
        surface.site_width = 1;
        surface.layer_thickness = 1;           
        surface.r2 = calc_r2(surface);
        surface.m2 = calc_m2(surface);
        surface = class(surface,'lpcvd_2DSurface');
    otherwise
        error('Wrong number of input arguments');
end